home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Misc / aa_m68k_Only / NDCamera.0.21 / Source / MiscSources.subproj / MiscStringCompat.m < prev    next >
Encoding:
Text File  |  1995-04-12  |  13.3 KB  |  525 lines

  1. //
  2. //    MiscStringCompat.m
  3. //        Written by Don Yacktman Copyright (c) 1993 by Don Yacktman.
  4. //                Version 1.95  All rights reserved.
  5. //        This notice may not be removed from this source code.
  6. //
  7. //    This object is included in the MiscKit by permission from the author
  8. //    and its use is governed by the MiscKit license, found in the file
  9. //    "LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
  10. //    for a list of all applicable permissions and restrictions.
  11. //    
  12.  
  13. #import <misckit/MiscString.h>
  14.  
  15. @implementation MiscString(Compat)
  16.  
  17. // This category includes methods to make the MiscString compatible
  18. // with other existing string classes.  This way, you can easily
  19. // replace your crufty old string class with a MiscString without
  20. // having to change the code.  Most methods are covers which simply
  21. // call the appropriate existing MiscString function.  The majority
  22. // of these methods actually add compatability with the MOString class,
  23. // but there is other stuff in here, too...
  24.  
  25. // None of the methods in this category add functionality; they are wrappers
  26. // around existing methods which allow programmers to use calls associated
  27. // with other string classes on the MiscString.  When I add compatability
  28. // with string classes, if there is a function that adds functionality, I
  29. // write a compatible method and place it into another category.  Only
  30. // redundant methods are in this category, which is why they are not
  31. // detailed in the documentation.
  32.  
  33. // If you have some _other_ string class, and would like to see
  34. // compatibility methods added to the MiscString to support that
  35. // class, too, let us know!
  36.  
  37. // Most of these methods are derived by Don Yacktman from code written
  38. // by Mike Ferris and David Lehn.
  39.  
  40. - takeStringValue:sender { return [self takeStringValueFrom:sender]; }
  41.  
  42. - clear
  43. {
  44.     [self freeString];
  45.     return self;
  46. }
  47.  
  48. - ( const char* ) string
  49. {
  50.    return [self stringValue];
  51. }
  52.  
  53. - setString: ( const char *) aString
  54. {
  55.     [self setStringValue:aString];
  56.     return self;
  57. }
  58.  
  59. - replaceChar: ( char ) aChar withChar: ( char ) replaceChar
  60. {
  61.     return [self replaceEveryInstanceOfChar:aChar withChar:replaceChar];
  62. }
  63.  
  64. - addToEndOfString: ( const char *) aString
  65. {
  66.     [self cat:aString];
  67.     return self;
  68. }
  69.  
  70. - addToFrontOfString: ( const char *) aString
  71. {
  72.     [self insert:aString at:0];
  73.     return self;
  74. }
  75.  
  76. - addCharToEndOfString: ( char ) aChar
  77. {
  78.     [self addChar:aChar];
  79.     return self;
  80. }
  81.  
  82. - addCharToFrontOfString: ( char ) aChar
  83. {
  84.     [self insertChar:aChar at:0];
  85.     return self;
  86. }
  87.  
  88. - ( int ) numberFields
  89. {
  90.     return [self numWords];
  91. }
  92.  
  93. - ( char * ) nthField: ( int ) fieldNumber useAsDelimiter: ( char ) c
  94. {
  95.     char * field;
  96.     id fieldString = [ self extractPart:(fieldNumber) useAsDelimiter:c ];
  97.     if (!fieldString) return NULL;
  98.     field = NXZoneMalloc( [ self zone ], [ fieldString length ] + 1 );
  99.     strcpy(field, [ fieldString stringValue ]);
  100.     [fieldString free];
  101.     return field;
  102. }
  103.  
  104. - ( char * ) nthField: ( int ) fieldNumber
  105. {    // have to do all this garbage to make sure we (1) don't leak memory
  106.     // and (2) we don't smash the stringValueAndFree buffer.  (Otherwise
  107.     // I would just use it, but that would make the MiscString badly
  108.     // non-reentrant.)  This works, anyway...though the obvious
  109.     // implementation would be this:
  110.     //
  111.     //        return [[self wordNum:fieldNumber] stringValueAndFree];
  112.  
  113.     static id tempBuffer = nil; id temp;
  114.  
  115.     if (!tempBuffer) tempBuffer = [MiscString new];
  116.     temp = [self wordNum:fieldNumber];
  117.     [tempBuffer setStringValue:[temp stringValue]];
  118.     [temp free];
  119.     return (char *)[tempBuffer stringValue];
  120. }
  121.  
  122. // this one kind of adds functionality, but by naming conventions it still
  123. // makes sense to put it here.
  124. - ( char * ) nthQuotedField: ( int ) fieldNumber
  125. {
  126.     return [ self nthField:fieldNumber*2 useAsDelimiter:'"' ];
  127. }
  128.  
  129. - ( char * ) lastField
  130. {
  131.     char * field;
  132.     id str = [ self extractPart:MISC_STRING_LAST useAsDelimiter:' ' ];
  133.     field = NXZoneMalloc([self zone], [str length] + 1);
  134.     strcpy(field, [str stringValue]);
  135.     [str free];
  136.     return field;
  137. }
  138.  
  139. - ( char * ) firstField
  140. {
  141.     char * field;
  142.     id str = [ self extractPart:MISC_STRING_FIRST useAsDelimiter:' ' ];
  143.     field = NXZoneMalloc([self zone], [str length] + 1);
  144.     strcpy(field, [str stringValue]);
  145.     [str free];
  146.     return field;
  147. }
  148.  
  149. - addStrings: ( const char *) fields,  ...
  150. {
  151.     va_list ptr;
  152.   
  153.     va_start( ptr, fields );
  154.     [self catStrings:fields, ptr];
  155.     va_end( ptr );       
  156.     return self;
  157. }
  158.  
  159. - replaceEveryInstanceOfChar:(char)aChar withChar:(char)replaceChar
  160. {
  161.     return [self replaceEveryOccurrenceOfChar:aChar
  162.             withChar:replaceChar caseSensitive:YES];
  163. }
  164.  
  165. - replaceEveryInstanceOfChar:(char)aChar with:(char)replaceChar
  166. {
  167.     return [self replaceEveryOccurrenceOfChar:aChar
  168.             withChar:replaceChar caseSensitive:YES];
  169. }
  170.  
  171. // The rest of the methods here are for compatability with the MOString
  172. // from the MOKit.
  173.  
  174. // warning:  the following MOString methods clash with MiscString methods
  175. //    of the same name.  You will have to check your code for uses of these
  176. //    methods and fix them appropriately to avoid serious problems.
  177. //    Group 1:  MOString wants string object, MiscString wants char *
  178. //        -insert:stringObject at:(int)position
  179. //        -cat:stringObject
  180. //    Note also that the MiscString doesn't support the unique string
  181. //    concept, so it cannot become a unique string.  Perhaps in the
  182. //    future there will be a MiscUniqueString class; I prefer that approach
  183. //    myself.  At any rate, this shouldn't affect the functionality when
  184. // using the MiscString compatibly.
  185.  
  186. - convertToUpper
  187. {
  188.     return [self toUpper];
  189. }
  190.  
  191. - convertToLower
  192. {
  193.     return [self toLower];
  194. }
  195.  
  196. - (size_t)recalcLength
  197. {
  198.     length = strlen(buffer);
  199.     return length;
  200. }
  201.  
  202. - (int)replaceAllOccurrencesOfChar:(char)oldChar with:(char)newChar
  203. {
  204.     [self replaceEveryOccurrenceOfChar:oldChar withChar:newChar];
  205.     return 0; // this information isn't available so we'll just return zero
  206. }
  207.  
  208. - (char)replaceCharAt:(int)index with:(char)newChar
  209. {
  210.     char tempChar = [self charAt:index];
  211.     [self replaceCharAt:index withChar:newChar];
  212.     return tempChar; 
  213. }
  214.  
  215. - insertStringValue:(const char *)s at:(int)position
  216. {
  217.     [self insert:s at:position];
  218.     return self;
  219. }
  220.  
  221. - preCatStringValue:(const char *)s
  222. {
  223.     return [self insert:s at:0];
  224. }
  225.  
  226. - preCat:stringObject
  227. {
  228.     return [self insertString:stringObject];
  229. }
  230.  
  231. - preCatFromFormat:(const char *)format, ...
  232. // Prepends the given format string after formatting before the contents
  233. // of the receiver.
  234. {
  235.     va_list param_list;
  236.  
  237.     va_start(param_list, format);
  238.     [self insertFromFormat:format, param_list];
  239.     va_end(param_list);
  240.     return self;
  241. }
  242.  
  243. - catStringValue:(const char *)s
  244. {
  245.     return [self cat:s];
  246. }
  247.  
  248. - (int)compare:stringObject caseSensitive:(BOOL)flag
  249. {
  250.     return [self compare:stringObject caseSensitive:flag 
  251.                     length:-1 withTable:NULL];
  252. }
  253.  
  254. - (int)compare:stringObject caseSensitive:(BOOL)flag length:(int)len
  255. {
  256.     return [self compare:stringObject caseSensitive:flag 
  257.                     length:len withTable:NULL];
  258. }
  259.  
  260. - (int)compare:stringObject caseSensitive:(BOOL)flag length:(int)len 
  261.             withTable:(NXStringOrderTable *)table
  262. {
  263.     int ret;
  264.     NXStringOrderTable *realTable = [self stringOrderTable]; // temp save
  265.     [self setStringOrderTable:table];
  266.     ret = [self compareTo:stringObject n:len caseSensitive:flag];
  267.     [self setStringOrderTable:realTable];
  268.     return ret;
  269. }
  270.  
  271. - (int)compareStr:(const char *)s
  272. {
  273.     return [self compareStr:s caseSensitive:YES length:-1 withTable:NULL];
  274. }
  275.  
  276. - (int)compareStr:(const char *)s caseSensitive:(BOOL)flag
  277. {
  278.     return [self compareStr:s caseSensitive:flag length:-1 withTable:NULL];
  279. }
  280.  
  281. - (int)compareStr:(const char *)s caseSensitive:(BOOL)flag length:(int)len
  282. {
  283.     return [self compareStr:s caseSensitive:flag length:len withTable:NULL];
  284. }
  285.  
  286. - (int)compareStr:(const char *)s caseSensitive:(BOOL)flag length:(int)len
  287.             withTable:(NXStringOrderTable *)table
  288. {
  289.     id ss = [[self class] newWithString:s];
  290.     int ret = [self compare:ss caseSensitive:flag length:len withTable:table];
  291.     [ss free];
  292.     return ret;
  293. }
  294.  
  295. - (int)endCompare:stringObject caseSensitive:(BOOL)flag
  296. {
  297.     return [self endCompare:stringObject 
  298.                     caseSensitive:flag length:-1 withTable:NULL];
  299. }
  300.  
  301. - (int)endCompare:stringObject caseSensitive:(BOOL)flag length:(int)len
  302. {
  303.     return [self endCompare:stringObject 
  304.                     caseSensitive:flag length:len withTable:NULL];
  305. }
  306.  
  307. - (int)endCompare:stringObject caseSensitive:(BOOL)flag length:(int)len 
  308.             withTable:(NXStringOrderTable *)table
  309. {
  310.     int ret;
  311.     NXStringOrderTable *realTable = [self stringOrderTable]; // temp save
  312.     [self setStringOrderTable:table];
  313.     ret = [self endCompareTo:stringObject n:len caseSensitive:flag];
  314.     [self setStringOrderTable:realTable];
  315.     return ret;
  316. }
  317.  
  318. - (int)endCompareStr:(const char *)s
  319. {
  320.     return [self endCompareStr:s caseSensitive:YES 
  321.                 length:-1 withTable:NULL];
  322. }
  323.  
  324. - (int)endCompareStr:(const char *)s caseSensitive:(BOOL)flag
  325. {
  326.     return [self endCompareStr:s caseSensitive:flag 
  327.                 length:-1 withTable:NULL];
  328. }
  329.  
  330. - (int)endCompareStr:(const char *)s caseSensitive:(BOOL)flag 
  331.             length:(int)len
  332. {
  333.     return [self endCompareStr:s caseSensitive:flag 
  334.                 length:len withTable:NULL];
  335. }
  336.  
  337. - (int)endCompareStr:(const char *)s caseSensitive:(BOOL)flag 
  338.             length:(int)len withTable:(NXStringOrderTable *)table
  339. {
  340.     id ss = [[self class] newWithString:s];
  341.     int ret = [self endCompare:ss caseSensitive:flag
  342.             length:len withTable:table];
  343.     [ss free];
  344.     return ret;
  345. }
  346.  
  347. - substringFrom:(int)start to:(int)end
  348. {
  349.     return [self midFrom:start to:end];
  350. }
  351.  
  352. - (int)positionOf:(char)aChar nthOccurrence:(int)n
  353. {
  354.     if (n<0) return [self rspotOf:aChar occurrenceNum:(-n) caseSensitive:YES];
  355.     return [self spotOf:aChar occurrenceNum:n caseSensitive:YES];
  356. }
  357.  
  358. - (int)countOccurrencesOf:(char)aChar
  359. {
  360.     return [self numOfChar:aChar caseSensitive:YES];
  361. }
  362.  
  363. - (size_t)strlen
  364. {
  365.     return length;
  366. }
  367.  
  368. - (const char *)strcpy:(const char *)s
  369. {
  370.     [self setStringValue:s];
  371.     return buffer;
  372. }
  373.  
  374. - (const char *)strncpy:(const char *)s :(size_t)n
  375. {
  376.     [self setStringValue:s n:(int)n fromZone:[self zone]];
  377.     return buffer;
  378. }
  379.  
  380. - (const char *)strcat:(const char *)s
  381. {
  382.     [self cat:s];
  383.     return buffer;
  384. }
  385.  
  386. - (const char *)strncat:(const char *)s :(size_t)n
  387. {
  388.     [self cat:s n:n fromZone:[self zone]];
  389.     return buffer;
  390. }
  391.  
  392. - (int)strcmp:(const char *)s
  393. {
  394.     if ((!buffer) || (!s)) return -2;
  395.     return strcmp(buffer, s);
  396. }
  397.  
  398. - (int)strncmp:(const char *)s :(size_t)n
  399. {
  400.     if ((!buffer) || (!s)) return -2;
  401.     return strncmp(buffer, s, n);
  402. }
  403.  
  404. - (const char *)strchr:(char)aChar
  405. {
  406.     if (buffer) return NULL;
  407.     return strchr(buffer, aChar);
  408. }
  409.  
  410. - (const char *)strrchr:(char)aChar
  411. {
  412.     if (!buffer) return NULL;
  413.     return strrchr(buffer, aChar);
  414. }
  415.  
  416. - (const char *)strpbrk:(const char *)breakChars
  417. {
  418.     if ((!buffer) || (!breakChars)) return NULL;
  419.     return strpbrk(buffer, breakChars);
  420. }
  421.  
  422. - (size_t)strspn:(const char *)acceptableChars
  423. {
  424.     if ((!buffer) || (!acceptableChars)) return -1;
  425.     return strspn(buffer, acceptableChars);
  426. }
  427.  
  428. - (size_t)strcspn:(const char *)breakChars
  429. {
  430.     if ((!buffer) || (!breakChars)) return 0;
  431.     return strcspn(buffer, breakChars);
  432. }
  433.  
  434. - initStringValue:(const char *)s
  435. {
  436.     return [self initString:s];
  437. }
  438.  
  439. - initStringValueNoCopy:(char *)s
  440. {    // we still copy it anyway; this could be implemented for effect a speedup
  441.     // if it makes that much difference...
  442.     return [self initString:s];
  443. }
  444.  
  445. - initStringValueNoCopy:(char *)s shouldFree:(BOOL)flag
  446. {
  447.     id ret = [self initString:s];
  448.     if (flag) NX_FREE(s);
  449.     return ret;
  450. }
  451.  
  452. - initStringValueUnique:(const char *)s
  453. {
  454.     return [self initString:s];
  455. }
  456.  
  457. - deepCopy
  458. {
  459.     return [self deepCopyFromZone:[self zone]];
  460. }
  461.  
  462. - deepCopyFromZone:(NXZone *)zone
  463. { // our copy from zone IS deep already...
  464.     return [self copyFromZone:zone];
  465. }
  466.  
  467. - shallowCopy
  468. {
  469.     return [self shallowCopyFromZone:[self zone]];
  470. }
  471.  
  472. - shallowCopyFromZone:(NXZone *)zone
  473. { // our copy from zone IS deep already...
  474.     return [self copyFromZone:zone];
  475. }
  476.  
  477. - setStringValueNoCopy:(const char *)s
  478. {    // we set the string value by copying anyway.
  479.     return [self setStringValue:s];
  480. }
  481.  
  482. - setStringValueNoCopy:(char *)s shouldFree:(BOOL)flag
  483. {
  484.     id ret = [self setStringValue:s];
  485.     if (flag) NX_FREE(s);
  486.     return ret;
  487. }
  488.  
  489. - setStringValueUnique:(const char *)s { return [self setStringValue:s]; }
  490. - setNull { return [self freeString]; }
  491. - makeUnique { return self; } // we don't support this at all.
  492. - setShouldFree:(BOOL)flag { return self; }
  493. - (unsigned int)count { return length; }
  494. - (BOOL)isNull { return [self emptyString]; }
  495. - (BOOL)isEmpty { return [self emptyString]; }
  496. - (BOOL)isUnique { return NO; }
  497. - (BOOL)shouldFree { return YES; }
  498.  
  499.  
  500.  
  501.  
  502. // MOPathString methods
  503. - (int)numberOfComponents { return [self numberOfPathComponents]; }
  504. - componentAt:(int)index { return [self pathComponentAt:index]; }
  505. - file { return [self fileName]; }
  506. - directory { return [self pathName]; }
  507. - (const char *)path { return [self stringValue]; }
  508. - (BOOL)isRelative { return [self isRelativePath]; }
  509. - (BOOL)isAbsolute { return [self isAbsolutePath]; }
  510. - (BOOL)isDirectory { return [self isFileOfType:Misc_Directory]; }
  511. - (BOOL)isPlainFile { return [self isFileOfType:Misc_PlainFile]; }
  512. - (BOOL)isSymbolicLink { return [self isFileOfType:Misc_SymbolicLink]; }
  513. - (BOOL)isCharacterSpecial { return [self isFileOfType:Misc_CharacterSpecial]; }
  514. - (BOOL)isBlockSpecial { return [self isFileOfType:Misc_BlockSpecial]; }
  515. - (BOOL)isSocket { return [self isFileOfType:Misc_Socket]; }
  516. - setPathSeparator:(char)c { return self; } // NO OP
  517. - setExtensionSeparator:(char)c { return self; } // NO OP
  518. - (char)pathSeparator { return '/'; }
  519. - (char)extensionSeparator { return '.'; }
  520. - setPath:(const char *)path { return [self setStringValue:path]; }
  521. - initPath:(const char *)path { return [self initStringValue:path]; }
  522. - (char *)buffer { return buffer; } // be careful with this!  don't muck it up!
  523.  
  524. @end
  525.